#!/usr/bin/env bash

# 早期退出测试
RACE=-race
TIMEOUT=timeout
FAILED=0

# 系统检查（同wc测试）
if [[ "$OSTYPE" = "darwin"* ]]; then
  if go version | grep 'go1.17.[012345]'; then
    RACE=
    echo '*** Turning off -race since it may not work on a Mac'
    echo '    with ' `go version`
  fi
fi

if timeout 2s sleep 1 > /dev/null 2>&1; then
  :
else
  if gtimeout 2s sleep 1 > /dev/null 2>&1; then
    TIMEOUT=gtimeout
  else
    TIMEOUT=
    echo '*** Cannot find timeout command; proceeding without timeouts.'
  fi
fi
if [ "$TIMEOUT" != "" ]; then
  TIMEOUT+=" -k 2s 180s "
fi

# 创建测试目录
rm -rf mr-tmp
mkdir mr-tmp || exit 1
cd mr-tmp || exit 1
rm -f mr-*

# 构建程序和插件
(cd ../../mrapps && go clean)
(cd .. && go clean)
(cd ../../mrapps && go build $RACE -buildmode=plugin early_exit.go) || exit 1
(cd .. && go build $RACE mrcoordinator.go) || exit 1
(cd .. && go build $RACE mrworker.go) || exit 1

echo '***' Starting early exit test.

# 创建用于检测进程退出的临时文件
DF=anydone$$
rm -f $DF

# 启动协调器（退出时创建标记文件）
($TIMEOUT ../mrcoordinator ../pg*txt ; touch $DF) &

# 等待协调器创建套接字
sleep 1

# 启动多个工作节点（退出时创建标记文件）
($TIMEOUT ../mrworker ../../mrapps/early_exit.so ; touch $DF) &
($TIMEOUT ../mrworker ../../mrapps/early_exit.so ; touch $DF) &
($TIMEOUT ../mrworker ../../mrapps/early_exit.so ; touch $DF) &

# 等待首个进程退出
jobs &> /dev/null
if [[ "$OSTYPE" = "darwin"* ]]; then
  # macOS 不支持 wait -n，使用循环检查
  while [ ! -e $DF ]; do
    sleep 0.2
  done
else
  # Linux 支持 wait -n，等待任一子进程退出
  wait -n
fi

# 首个进程退出后，立即收集当前输出
rm -f $DF
sort mr-out* | grep . > mr-wc-all-initial

# 等待所有进程退出
wait

# 收集最终输出并比较
sort mr-out* | grep . > mr-wc-all-final
if cmp mr-wc-all-final mr-wc-all-initial; then
  echo '---' early exit test: PASS
else
  echo '---' output changed after first worker exited
  echo '---' early exit test: FAIL
  FAILED=1
fi

# 清理临时文件
rm -f mr-*

exit $FAILED